package com.cltolarva;

import java.util.ArrayList;

import clanalyser.CLAnalyser;
import clanalyser.contract.Clause;
import clanalyser.parser.ParsingException;

public class CheckCLConflict {

	public ArrayList<CLMonitor> activeMonitors;
	CLMonitorList clml;

	public CheckCLConflict(String clFile) {
		clml = new CLMonitorList(clFile);

		activeMonitors = new ArrayList<CLMonitor>();
	}

	public void addActiveMonitor(CLMonitor clm) {

		activeMonitors.add(clm);
	}

	public void removeActiveMonitor(CLMonitor clm) {

		activeMonitors.remove(clm);
	}

	// return true if monitor is added or monitor is allredy added
	// return false if conflicting with previously added monitor
	public boolean addMonitor(String methodName) {
		CLMonitor clm = null;
		for (int i = 0; i < this.clml.allMonitors.size(); i++) {

			if (this.clml.allMonitors.get(i).getRelatedMethod()
					.equals(methodName)) {
				clm = new CLMonitor(
						this.clml.allMonitors.get(i).getClContact(),
						this.clml.allMonitors.get(i).getRelatedMethod(),
						this.clml.allMonitors.get(i).isActive());
			}

		}

		// if the monitor is already exist
		if (this.isActive(clm)) {

			System.out.println("Monitor Already activated");
			return true;
		}

		// if conflicting CL
		if (this.isConflicting(this.activeMonitors, clm.getClContact())) {
			System.out.println("Cannot add monitor ...Conflict in CL CONTRACT");
			return false;

		} else {
			System.out.println("New Monitor Added");
			clm.setActive(true);
			this.addActiveMonitor(clm);
			return true;
		}
	}

	public CLMonitor getActiveMonitorFromMethod(String MethodName) {

		CLMonitor clm = new CLMonitor("tempContract", "tempMethod", false);
		for (int i = 0; i < this.activeMonitors.size(); i++) {

			if (this.activeMonitors.get(i).getRelatedMethod()
					.equals(MethodName)) {

				return (CLMonitor) activeMonitors.get(i);
			}

		}

		return clm;

	}

	public CLMonitor getActiveMonitorFromCL(String contractCL) {

		CLMonitor clm = new CLMonitor("tempContract", "tempMethod", false);
		for (int i = 0; i < this.activeMonitors.size(); i++) {

			if (this.activeMonitors.get(i).getClContact().equals(contractCL)) {

				return (CLMonitor) activeMonitors.get(i);
			}

		}

		return clm;

	}

	public boolean isActive(CLMonitor clm) {

		for (int i = 0; i < this.activeMonitors.size(); i++) {

			if (this.activeMonitors.get(i).getClContact()
					.equals(clm.getClContact())
					&& this.activeMonitors.get(i).getRelatedMethod()
							.equals(clm.getRelatedMethod())) {

				return true;
			}

		}
		return false;
	}

	public void printRes() {

		System.out.println(this.activeMonitors.size());
		for (int i = 0; i < activeMonitors.size(); i++) {

			String clFormula = this.activeMonitors.get(i).getClContact();
			String relatedMethod = this.activeMonitors.get(i)
					.getRelatedMethod();
			System.out.println(clFormula + "--------------->" + relatedMethod);

		}
	}

	public boolean isConflicting(ArrayList<CLMonitor> activeMonitorsList,
			String newCL) {

		CLAnalyser appAnalyser = new CLAnalyser();
		appAnalyser.clearContract();

		// adding allactive contract in clan analyzer
		for (int i = 0; i < activeMonitorsList.size(); i++) {

			appAnalyser.addClause(new Clause(activeMonitorsList.get(i)
					.getClContact().toString()));
		}

		appAnalyser.addClause(new Clause(newCL));

		appAnalyser.addActionConflictDefinition("");
		try {
			appAnalyser.AnalyseContract(true);

			if (appAnalyser.getGraph().conflictFree()) {
				System.out.println("Contract is Conflict free\n");
				return false;
			} else {
				System.out.println("Contract has a Conflict\n");
				return true;
			}

		} catch (ParsingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return true;
	}

	public static void main(String[] args) {

		CheckCLConflict ckc = new CheckCLConflict(
				"D:\\JavaConCommandline2012\\CL_CONTRACT.txt");
		System.out.print(ckc.clml.allMonitors.size());
		System.out.print(ckc.activeMonitors.size());
		ckc.addMonitor("login");
		// ckc.addMonitor("logout");
		ckc.addMonitor("login");
		System.out.print(ckc.clml.allMonitors.size());
		System.out.print(ckc.activeMonitors.size());
		ckc.addMonitor("login");
		System.out.print(ckc.clml.allMonitors.size());
		System.out.print(ckc.activeMonitors.size());
		/*
		 * boolean b = true;
		 * 
		 * String clContractTemp = "[login]P(logout)^F(request)^F(login)";
		 * String methodTemp = "login";
		 * 
		 * CLMonitor clm1 = new CLMonitor(clContractTemp, methodTemp, true);
		 * 
		 * b = ckc.isConflicting(ckc.activeMonitors, clContractTemp);
		 * System.out.print("Conflicting: " + b + "\n"); if (b == false) {
		 * ckc.addActiveMonitor(clm1); }
		 * 
		 * clContractTemp = "[logout]F(logout)"; methodTemp = "logout";
		 * CLMonitor clm2 = new CLMonitor(clContractTemp, methodTemp, true);
		 * 
		 * b = ckc.isConflicting(ckc.activeMonitors, clContractTemp);
		 * System.out.print("Conflicting: " + b + "\n"); if (b == false) {
		 * ckc.addActiveMonitor(clm2); }
		 * 
		 * CLMonitor clm3 = new CLMonitor(clContractTemp, methodTemp, false);
		 * 
		 * System.out.print(ckc.isActive(clm3));
		 */
	}

}
